home *** CD-ROM | disk | FTP | other *** search
- /*
- File: UHIDTest.c
-
- Contains: xxx put contents here xxx
-
- Version: xxx put version here xxx
-
- Copyright: © 1999 by Apple Computer, Inc., all rights reserved.
-
- File Ownership:
-
- DRI: xxx put dri here xxx
-
- Other Contact: xxx put other contact here xxx
-
- Technology: xxx put technology here xxx
-
- Writers:
-
- (BWS) Brent Schorsch
-
- Change History (most recent first):
-
- <SP6> 3/20/99 BWS Update to lastest HIDOpenReportDescriptor API
- <SP5> 3/7/99 BWS Add Simulate ISp enumeration - similar code to ISp driver
- <SP4> 3/7/99 BWS Print out caps usage page and usage. Print all usages in hex
- <SP3> 3/7/99 BWS Implemented get capabilities and print parsed data
- <SP2> 3/5/99 BWS Added HIDLib calls
- */
-
- #include <MacTypes.h>
-
- #include <SIOUX.h>
- #include <LowMem.h>
- #include <USB.h>
- #include <InputSprocket.h>
- #include "HID.h"
- //#include "UniversalHIDModule.h"
-
- #include <stdarg.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- //#include "HIDPriv.h"
-
- // extern protos
- extern void PrintHIDReport(UInt8 * reportDesc, UInt32 length);
-
-
- // globals
-
- // quit state
- Boolean gShouldQuit = false;
-
- // steps of process
- SInt32 gStep;
- char gStepId[255];
-
- // 'safe' (delayed) printf
- enum { kPrintfBufferSize = 1024 * 32 };
-
- UInt32 gMaxPacketSize;
- char gPrintfBuffer1[kPrintfBufferSize + 256];
- char gPrintfBuffer2[kPrintfBufferSize + 256];
- char * gInsertPrintfBuffer;
- char * gFreePrintfBuffer;
- UInt32 gInsertIndex = 0;
-
- enum
- {
- kPrint_AsHex = 1,
- kPrint_AsBinary,
- kPrint_ParseButtons,
- kPrint_ParseBoth,
- kPrint_SimulateISp
- };
-
- UInt32 gPrint_AsType;
-
- // HID stuff
-
- // these constants are from the USB HID Usage Table spec
- enum
- {
- kHIDPage_Generic = 1,
- kHIDUsage_Joystick = 0x04,
- kHIDUsage_Gamepad = 0x05,
- kHIDUsage_X = 0x30,
- kHIDUsage_Y = 0x31,
- kHIDUsage_Z = 0x32,
- kHIDUsage_Rx = 0x33,
- kHIDUsage_Ry = 0x34,
- kHIDUsage_Rz = 0x35,
- kHIDUsage_Slider = 0x36,
- kHIDUsage_Dial = 0x37,
- kHIDUsage_Wheel = 0x38,
- kHIDUsage_HatSwitch = 0x39,
-
- kHIDPage_Simulation = 2,
- kHIDUsage_Rudder = 0xBA,
- kHIDUsage_Throttle = 0xBB,
-
- kHIDPage_Button = 9
- };
-
- // these constants are used to describe specific values for an element (a usbElementKey)
- enum
- {
- // it is important that all buttons come first and start at 1
- kUSB_button1_element = 1,
- kUSB_button2_element,
- kUSB_button3_element,
- kUSB_button4_element,
- kUSB_button5_element,
- kUSB_button6_element,
- kUSB_button7_element,
- kUSB_button8_element,
- kUSB_button9_element,
- kUSB_button10_element,
- kUSB_button11_element,
- kUSB_button12_element,
- kUSB_button13_element,
- kUSB_button14_element,
- kUSB_button15_element,
- kUSB_button16_element,
- kUSB_trigger_element,
- kUSB_buttonStart_element,
- kUSB_buttonSelect_element,
- kUSB_povhat_element,
- kUSB_povhat4_element,
- kUSB_dpad_element,
- kUSB_dpad4_element,
- kUSB_xaxis_element,
- kUSB_yaxis_element,
- kUSB_throttle_element,
- kUSB_rudder_element,
- kUSB_trim_element,
- kUSB_gas_element,
- kUSB_brake_element,
- kUSB_axis_element
- };
-
- enum
- {
- kStrListResource_DefaultNames = 128
- };
-
- enum
- {
- kStrList_DefaultNames_Trigger = 1,
- kStrList_DefaultNames_LeftTrigger,
- kStrList_DefaultNames_RightTrigger,
- kStrList_DefaultNames_LeftIndexTop,
- kStrList_DefaultNames_LeftIndexBottom,
- kStrList_DefaultNames_RightIndexTop,
- kStrList_DefaultNames_RightIndexBottom,
- kStrList_DefaultNames_ThumbLeftButton,
- kStrList_DefaultNames_ThumbCenterButton,
- kStrList_DefaultNames_ThumbRightButton,
- kStrList_DefaultNames_ThumbTopButton,
- kStrList_DefaultNames_ThumbBottomButton,
- kStrList_DefaultNames_AButton,
- kStrList_DefaultNames_BButton,
- kStrList_DefaultNames_CButton,
- kStrList_DefaultNames_DButton,
- kStrList_DefaultNames_EButton,
- kStrList_DefaultNames_FButton,
- kStrList_DefaultNames_XButton,
- kStrList_DefaultNames_YButton,
- kStrList_DefaultNames_ZButton,
- kStrList_DefaultNames_MButton,
- kStrList_DefaultNames_TAButton,
- kStrList_DefaultNames_TBButton,
- kStrList_DefaultNames_F1Button,
- kStrList_DefaultNames_F2Button,
- kStrList_DefaultNames_F3Button,
- kStrList_DefaultNames_F4Button,
- kStrList_DefaultNames_F5Button,
- kStrList_DefaultNames_F6Button,
- kStrList_DefaultNames_F7Button,
- kStrList_DefaultNames_F8Button,
- kStrList_DefaultNames_YellowButton,
- kStrList_DefaultNames_RedButton,
- kStrList_DefaultNames_GreenButton,
- kStrList_DefaultNames_BlueButton,
- kStrList_DefaultNames_StartButton,
- kStrList_DefaultNames_SelectButton,
- kStrList_DefaultNames_ShiftButton,
- kStrList_DefaultNames_LeftShiftButton,
- kStrList_DefaultNames_RightShiftButton,
- kStrList_DefaultNames_SensorButton,
- kStrList_DefaultNames_Button1,
- kStrList_DefaultNames_Button2,
- kStrList_DefaultNames_Button3,
- kStrList_DefaultNames_Button4,
- kStrList_DefaultNames_Button5,
- kStrList_DefaultNames_Button6,
- kStrList_DefaultNames_Button7,
- kStrList_DefaultNames_Button8,
- kStrList_DefaultNames_Button9,
- kStrList_DefaultNames_Button10,
- kStrList_DefaultNames_Button11,
- kStrList_DefaultNames_Button12,
- kStrList_DefaultNames_Button13,
- kStrList_DefaultNames_Button14,
- kStrList_DefaultNames_Button15,
- kStrList_DefaultNames_Button16,
- kStrList_DefaultNames_Button,
- kStrList_DefaultNames_POVHat,
- kStrList_DefaultNames_DPad,
- kStrList_DefaultNames_XAxis,
- kStrList_DefaultNames_YAxis,
- kStrList_DefaultNames_XTilt,
- kStrList_DefaultNames_YTilt,
- kStrList_DefaultNames_Twist,
- kStrList_DefaultNames_Throttle,
- kStrList_DefaultNames_Trim,
- kStrList_DefaultNames_Rudder,
- kStrList_DefaultNames_Axis,
- kStrList_DefaultNames_Wheel,
- kStrList_DefaultNames_Gas,
- kStrList_DefaultNames_Brake,
- kStrList_DefaultNames_Error
- };
-
- enum
- {
- kButtonElement = 1,
- kValueElement = 2
- };
-
- struct HIDElement
- {
- UInt32 type;
- UInt32 capsIndex;
- HIDUsage usagePage;
- HIDUsage usage;
- UInt32 key;
- SInt32 min;
- SInt32 max;
- SInt32 stringIndex;
- };
- typedef struct HIDElement HIDElement;
-
- HIDCaps gHIDCaps;
- HIDButtonCaps * gHIDButtonCaps;
- HIDValueCaps * gHIDValueCaps;
- HIDElement * gHIDElements;
- UInt32 gHIDElementCount = 0;
-
- enum { kMaxReportDescSize = 1024 };
- UInt8 gReportDesc[kMaxReportDescSize];
- UInt32 gReportDescLength;
-
- HIDPreparsedDataRef gPreparsedDataRef;
- HIDPreparsedData gPreparsedData;
- UInt32 gMaxUsageListLength = 0;
- HIDUsageAndPage * gPreviousDownButtons = nil;
- HIDUsageAndPage * gCurrentDownButtons = nil;
-
- // lists of dispatch tables
- enum { kMaxDevices = 128 };
-
- UHIDModuleDispatchTablePtr gUHID_dispatchTables[kMaxDevices];
- int gUHID_count = 0;
- UHIDModuleDispatchTablePtr gCurrentUHID_dispatchTable;
- UHIDModuleConnectionID gCurrentUHIDModuleConnectionID;
-
- USBHIDModuleDispatchTablePtr gMouse_dispatchTables[kMaxDevices];
- int gMouse_count = 0;
-
- // macros
-
- #define VERIFY(x) if (x) { FailCode(x); return; }
-
- #define FAILMSG(x) { FailMsg(x); return; }
- #define FAILCODE(x) { FailCode(x); return; }
-
- #define FFAILMSG(x) { FailMsg(x); return false; }
- #define FFAILCODE(x) { FailCode(x); return false; }
-
- // protos
-
- void ShowFourByte(OSType fourByte);
-
- void ExitProc (void);
- void DoHIDTest (void);
-
- void GetButtonCapabilities (void);
- void GetValueCapabilities (void);
- void PrintButtonCapabilities (HIDCaps hidCaps, HIDButtonCaps * hidButtonCaps);
- void PrintValueCapabilities (HIDCaps hidCaps, HIDValueCaps * hidValueCaps);
-
- void ClaimAndInstallHandler (void);
- void RemoveHandlerAndRelease (void);
- void myUniversalInterruptProc(void * theData, UInt32 refcon);
-
-
- OSStatus HidP_PrintAllInputValues
- (UInt32 iCollection,
- HIDPreparsedDataPtr ptPreparsedData,
- char *psReport,
- int iReportLength);
-
-
- int safeprintf(const char *format, ...);
-
- void PrintPreparsedData (void);
- void PrintCollectionItems (UInt32 firstCollection, UInt32 collectionCount, char * indent);
- void PrintReportItems (UInt32 firstReportItem, UInt32 reportItemCount, char * indent);
- void PrintUsageItems (UInt32 firstUsageItem, UInt32 usageItemCount, char * indent);
-
- void SimulateISpEnumeration (void);
- OSStatus PrintHIDElements (void);
- OSStatus BuildHIDElements (void);
- UInt32 CountHIDElements(void);
- OSStatus InitializeHIDElement(HIDElement * hidElement);
- SInt32 ParseElementValue (UInt32 inElementIndex, Ptr inBuffer);
-
- // code
-
- static Boolean Progress(UInt32 inItr, UInt32 inTotal, UInt32 inNumReports, char *string)
- {
- UInt32 everyNTimes = inTotal / inNumReports;
-
- if (everyNTimes == 0) { everyNTimes = 1; }
-
- if (inItr == 0) { return false; }
-
- if ((inItr % everyNTimes) == 0)
- {
- UInt32 percent = (inItr * 100) / inTotal;
- sprintf(string, "%d%% [%d of %d]", percent, inItr, inTotal);
- return true;
- }
-
- return false;
- }
-
- static void InitStep(char *msg)
- {
- gStep = 0;
- sprintf(gStepId, "%3d");
-
- if (msg == nil)
- {
- printf("step %s\n", gStepId);
- }
- else
- {
- printf("step %s %s\n",gStepId, msg);
- }
- }
-
- static void NextStep(char *msg)
- {
- long this_app_memory;
- long this_sys_memory;
- static Boolean first_time = true;
- static long last_app_memory;
- static long last_sys_memory;
-
- gStep++;
- sprintf(gStepId, "%3d", gStep);
-
- this_app_memory = FreeMem();
- this_sys_memory = FreeMemSys();
-
- if (first_time)
- {
- first_time = false;
- }
- else
- {
- long delta_app_memory = last_app_memory - this_app_memory;
- long delta_sys_memory = last_sys_memory - this_sys_memory;
-
- printf("step %s ending app mem = %d sys mem = %d\n", gStepId, this_app_memory, this_sys_memory);
- printf("step %s delta app mem = %d sys mem = %d\n", gStepId, delta_app_memory, delta_sys_memory);
- }
-
- if (msg == nil)
- {
- printf("step %s\n", gStepId);
- }
- else
- {
- printf("step %s %s\n",gStepId, msg);
- }
-
- printf("step %s starting app mem = %d sys mem = %d\n", gStepId, this_app_memory, this_sys_memory);
-
- last_app_memory = this_app_memory;
- last_sys_memory = this_sys_memory;
- }
-
- static void FailMsg(char *failure)
- {
- printf("step %s FAILED reason = %s\n", gStepId, failure);
- }
-
- static void FailCode(OSStatus errorCode)
- {
- printf("step %s FAILED errorCode = %d\n", gStepId, errorCode);
- }
-
- static void StatusMsg(char *msg)
- {
- printf("step %s status msg = %s\n",gStepId, msg);
- }
-
- void ShowFourByte(OSType fourByte)
- {
- putchar(((fourByte & 0xff000000) >> 24));
- putchar(((fourByte & 0x00ff0000) >> 16));
- putchar(((fourByte & 0x0000ff00) >> 8));
- putchar(((fourByte & 0x000000ff) >> 00));
- }
-
- void main(void)
- {
- OSErr status = noErr;
- CFragConnectionID usbConnID;
- USBDeviceRef usbDeviceRef;
- CFragSymbolClass symClass;
- UHIDModuleDispatchTablePtr uHID_dispatchTable;
- // USBHIDModuleDispatchTablePtr mouse_dispatchTable;
- UInt16 vendor;
- UInt16 product;
- THz currentZone;
-
-
- #if defined(__MWERKS__)
- // tell SIOUX to shut up
- SIOUXSettings.autocloseonquit = false;
- SIOUXSettings.asktosaveonclose = false;
- SIOUXSettings.columns = 120;
- SIOUXSettings.rows = 70;
- #endif
-
- printf("starting up...\n");
-
- printf("searching for universal HID devices\n");
-
- usbDeviceRef = 0;
- while (status == noErr && gUHID_count < kMaxDevices)
- {
- printf ("searching for next device...\n");
-
- status = USBGetNextDeviceByClass (&usbDeviceRef, &usbConnID, kUSBHIDClass, kUSBCompositeSubClass, kUSBNoInterfaceProtocol);
- if (status)
- {
- if (status != kUSBNotFound && status != fnfErr)
- FailCode (status);
- continue;
- }
-
- printf ("candidate found (connID: %00000008x), searching for symbol...\n", usbConnID);
-
- // need to be in the system zone when we search for the symbol
- currentZone = GetZone ();
- SetZone (SystemZone ());
- status = FindSymbol (usbConnID, "\pTheUHIDModuleDispatchTable", (Ptr *)&uHID_dispatchTable, &symClass);
- SetZone (currentZone);
-
- // if we failed to find it, go on to the next device
- if (status)
- {
- FailCode (status);
- status = noErr;
- continue;
- }
-
- printf("symbol found, checking versions...\n");
-
- // version checking
- if (uHID_dispatchTable->dispatchTableCurrentVersion < kOldestCompatableDispatchTableVersion)
- {
- printf (" DispatchTable current version (%d) too old (%d)\n",
- uHID_dispatchTable->dispatchTableCurrentVersion, kOldestCompatableDispatchTableVersion);
- continue;
- }
- if (uHID_dispatchTable->dispatchTableOldestVersion > kCurrentDispatchTableVersion)
- {
- printf (" DispatchTable oldest version (%d) too new (%d)\n",
- uHID_dispatchTable->dispatchTableOldestVersion, kCurrentDispatchTableVersion);
- continue;
- }
-
- gUHID_dispatchTables[gUHID_count++] = uHID_dispatchTable;
-
- (UHIDInstallInterruptProcPtr)(*(uHID_dispatchTable->pUHIDGetDeviceInfo))(kUHIDGetVenderID, &vendor);
- (UHIDInstallInterruptProcPtr)(*(uHID_dispatchTable->pUHIDGetDeviceInfo))(kUHIDGetProductID, &product);
- printf("version check success, valid device (Vender:%0004X Product:%0004X).\n", vendor, product);
- }
-
- while (gUHID_count > 0 && !gShouldQuit)
- DoHIDTest();
-
- printf("quitting...\n");
- }
-
- void ExitProc (void)
- {
- RemoveHandlerAndRelease ();
- }
-
- void DoHIDTest (void)
- {
- OSErr status = noErr;
- UHIDModuleDispatchTablePtr uHID_dispatchTable;
- // USBHIDModuleDispatchTablePtr mouse_dispatchTable;
- UInt16 vendor;
- UInt16 product;
- int index;
- char string[256];
-
- choosedevice:
- // ••• memory leak here, but who cares for now... (We never dispose of these)
- gHIDElementCount = 0;
-
- printf ("\nChoose a device:\n");
-
- // choice to quit
- printf ("1. Exit\n");
-
- // print out UHID choices
- index = 0;
- while (index < gUHID_count)
- {
- uHID_dispatchTable = gUHID_dispatchTables[index];
- (UHIDInstallInterruptProcPtr)(*(uHID_dispatchTable->pUHIDGetDeviceInfo))(kUHIDGetVenderID, &vendor);
- (UHIDInstallInterruptProcPtr)(*(uHID_dispatchTable->pUHIDGetDeviceInfo))(kUHIDGetProductID, &product);
-
- printf ("%d. Vender:%0004X Product:%0004X\n", index + 2, vendor, product);
- index++;
- }
-
- // • todo • print out mouse choices
-
- // get user choice
- printf ("Selection: ");
- gets (string);
- index = atoi (string);
- printf ("\n");
-
- // handle the quit case
- if (index == 1)
- {
- gShouldQuit = true;
- return;
- }
-
- // setup for this device
- uHID_dispatchTable = gCurrentUHID_dispatchTable = gUHID_dispatchTables[index - 2];
-
- // init the printf double buffer
- gInsertPrintfBuffer = gPrintfBuffer1;
- gFreePrintfBuffer = gPrintfBuffer2;
- gInsertIndex = 0;
-
- // get the max packet size
- gMaxPacketSize = 0;
- (UHIDInstallInterruptProcPtr)(*(uHID_dispatchTable->pUHIDGetDeviceInfo))(kUHIDGetMaxPacketSize, &gMaxPacketSize);
- printf("Max packet size = %d\n", gMaxPacketSize);
-
- printf("Printing the report descriptor\n", status);
-
- // print the HID report descriptor
- gReportDescLength = sizeof (gReportDesc);
- status = (*uHID_dispatchTable->pUHIDGetHIDDescriptor)(kUSBReportDesc, 0, &gReportDescLength, gReportDesc);
- if (status)
- printf("*** Error (%d) on Get Report Descriptor Device\n", status);
- else
- PrintHIDReport(gReportDesc, gReportDescLength);
-
- // setup the HID stuff
- status = HIDOpenReportDescriptor (gReportDesc, gReportDescLength, &gPreparsedDataRef, kHIDFlag_StrictErrorChecking);
- if (status)
- printf("*** Error (%d) on HIDOpenDescriptor (strict error checking) \n", status);
-
- // if error, less error checking on the HID stuff
- if (status)
- {
- status = HIDOpenReportDescriptor (gReportDesc, gReportDescLength, &gPreparsedDataRef, 0);
- if (status)
- printf("*** Error (%d) on HIDOpenDescriptor\n", status);
- else
- printf("HIDOpenDescriptor (lax error checking) succeeded. \n", status);
- }
-
- // allocate our buffers
- gMaxUsageListLength = HIDMaxUsageListLength (kHIDInputReport, 0, gPreparsedDataRef);
- printf("Number of buttons (max usage list length) = %ld\n", gMaxUsageListLength);
-
- gPreviousDownButtons = (HIDUsageAndPage *) NewPtr (gMaxUsageListLength * sizeof (HIDUsageAndPage));
- if (gPreviousDownButtons == nil)
- printf("*** Error (%d) on NewPtr for gPreviousDownButtons\n", MemError());
-
- gCurrentDownButtons = (HIDUsageAndPage *) NewPtr (gMaxUsageListLength * sizeof (HIDUsageAndPage));
- if (gCurrentDownButtons == nil)
- printf("*** Error (%d) on NewPtr for gCurrentDownButtons\n", MemError());
-
- printf("gPreviousDownButtons = %lx, gCurrentDownButtons = %lx\n", gPreviousDownButtons, gCurrentDownButtons);
-
- whattoget:
- printf ("1. Exit\n");
- printf ("2. Choose another device\n");
- printf ("3. Get data\n");
- printf ("4. Get button capabilities\n");
- printf ("5. Get value capabilities\n");
- printf ("6. Print preparsed data\n");
- printf ("7. Simulate ISp Enumeration\n");
-
- // get user choice
- printf ("Selection: ");
- gets (string);
- index = atoi (string);
- printf ("\n");
-
- switch (index)
- {
- // exit
- case 1:
- gShouldQuit = true;
- goto close;
-
- case 2:
- goto choosedevice;
-
- case 3:
- break;
-
- case 4:
- GetButtonCapabilities();
- goto whattoget;
-
- case 5:
- GetValueCapabilities();
- goto whattoget;
-
- case 6:
- PrintPreparsedData();
- goto whattoget;
-
- case 7:
- SimulateISpEnumeration();
- goto whattoget;
-
- default:
- goto whattoget;
- }
-
-
- getdata:
-
- printf ("1. Exit\n");
- printf ("2. Previous menu\n");
- printf ("3. Display raw bits as hex\n");
- printf ("4. Display raw bits as binary\n");
- printf ("5. Display parsed buttons\n");
- printf ("6. Display parsed values and buttons\n");
- if (gHIDElementCount > 0)
- printf ("7. Simulate ISp\n");
-
- // get user choice
- printf ("Selection: ");
- gets (string);
- index = atoi (string);
- printf ("\n");
-
-
- // make as binary the default, and use in the unimplemented cases?
- gPrint_AsType = kPrint_AsBinary;
-
- switch (index)
- {
- // exit
- case 1:
- gShouldQuit = true;
- goto close;
-
- case 2:
- goto whattoget;
-
- case 3:
- gPrint_AsType = kPrint_AsHex;
- break;
-
- case 4:
- gPrint_AsType = kPrint_AsBinary;
- break;
-
- case 5:
- gPrint_AsType = kPrint_ParseButtons;
- break;
-
- case 6:
- gPrint_AsType = kPrint_ParseBoth;
- break;
-
- case 7:
- if (gHIDElementCount > 0)
- gPrint_AsType = kPrint_SimulateISp;
- else
- goto getdata;
- break;
-
- default:
- goto getdata;
- }
-
- ClaimAndInstallHandler();
-
- // get data
-
- printf("getting data (press command to end)\n");
-
- while (1)
- {
- KeyMap theKeys;
-
- if (gInsertIndex) // if we have data in the queue, then printf it
- {
- char * temp = gInsertPrintfBuffer;
-
- gInsertPrintfBuffer = gFreePrintfBuffer; // must do 1st! - atomic switch
- gInsertIndex = 0; // _technically_ bad, could possibly miss some data
-
- gFreePrintfBuffer = temp;
-
- printf(temp);
- fflush(stdout);
- }
-
-
- GetKeys(theKeys);
-
- if ((theKeys[1] & 0x8000))
- {
- break;
- }
-
- SIOUXHandleOneEvent(nil);
- }
-
-
- RemoveHandlerAndRelease ();
-
-
- if (!gShouldQuit)
- goto getdata;
- close:
-
- status = HIDCloseReportDescriptor (gPreparsedDataRef);
- if (status)
- printf("*** Error (%d) on HIDCloseDescriptor\n", status);
-
- DisposePtr ((void *) gPreviousDownButtons);
- gPreviousDownButtons = nil;
-
- DisposePtr ((void *) gCurrentDownButtons);
- gCurrentDownButtons = nil;
-
- printf("finished\n\n");
- }
-
- void GetButtonCapabilities(void)
- {
- OSStatus err = noErr;
-
- HIDCaps hidCaps;
- HIDButtonCaps * hidButtonCaps = nil;
-
- // get the overall capabilities of the device
- if (err == noErr)
- err = HIDGetCaps (gPreparsedDataRef, &hidCaps);
-
- // allocate space for button caps
- if (err == noErr)
- {
- hidButtonCaps = (HIDButtonCaps *) NewPtrSysClear(sizeof(HIDButtonCaps) * hidCaps.numberInputButtonCaps);
- if (hidButtonCaps == nil)
- {
- printf ("\n•• Failed to allocate space for ButtonCaps\n");
- err = memFullErr;
- }
- }
-
- // get the button capabilities
- if (err == noErr)
- err = HIDGetButtonCaps (kHIDInputReport, hidButtonCaps, &hidCaps.numberInputButtonCaps, gPreparsedDataRef);
-
- // print what we found
- if (err == noErr)
- PrintButtonCapabilities (hidCaps, hidButtonCaps);
-
- // dispose the memory
- if (hidButtonCaps != nil)
- DisposePtr((LogicalAddress) hidButtonCaps);
- }
-
- void GetValueCapabilities (void)
- {
- OSStatus err = noErr;
-
- HIDCaps hidCaps;
- HIDValueCaps * hidValueCaps = nil;
-
- // get the overall capabilities of the device
- if (err == noErr)
- err = HIDGetCaps (gPreparsedDataRef, &hidCaps);
-
- // allocate space for value caps
- if (err == noErr)
- {
- hidValueCaps = (HIDValueCaps *) NewPtrSysClear(sizeof(HIDValueCaps) * hidCaps.numberInputValueCaps);
- if (hidValueCaps == nil)
- {
- err = memFullErr;
- printf ("\n•• Failed to allocate space for ValueCaps\n");
- }
- }
-
- // get the value capabilities
- if (err == noErr)
- err = HIDGetValueCaps (kHIDInputReport, hidValueCaps, &hidCaps.numberInputValueCaps, gPreparsedDataRef);
-
- // print what we found
- if (err == noErr)
- PrintValueCapabilities (hidCaps, hidValueCaps);
-
- // dispose the memory
- if (hidValueCaps != nil)
- DisposePtr((LogicalAddress) hidValueCaps);
- }
-
- void PrintButtonCapabilities (HIDCaps hidCaps, HIDButtonCaps * hidButtonCaps)
- {
- UInt32 index;
- UInt32 reportID = 0;
-
- printf("%d buttons (device usage: %X on page: %d)\n",
- hidCaps.numberInputButtonCaps,
- hidCaps.usage,
- hidCaps.usagePage);
- for (index = 0; index < hidCaps.numberInputButtonCaps; index++)
- {
- if (reportID != hidButtonCaps[index].reportID)
- {
- reportID = hidButtonCaps[index].reportID;
- printf("Report ID: %d\n", reportID);
- }
-
- if (hidButtonCaps[index].isRange)
- printf("%X-%X:%d\n",
- hidButtonCaps[index].u.range.usageMin,
- hidButtonCaps[index].u.range.usageMax,
- hidButtonCaps[index].usagePage);
- else
- printf("%X:%d\n",
- hidButtonCaps[index].u.notRange.usage,
- hidButtonCaps[index].usagePage);
- }
-
- printf("\n\n");
- }
- void PrintValueCapabilities (HIDCaps hidCaps, HIDValueCaps * hidValueCaps)
- {
- UInt32 index;
- UInt32 reportID = 0;
-
- printf("%d values (device usage:%d on page:%d\n",
- hidCaps.numberInputValueCaps,
- hidCaps.usage,
- hidCaps.usagePage);
- for (index = 0; index < hidCaps.numberInputValueCaps; index++)
- {
- if (reportID != hidValueCaps[index].reportID)
- {
- reportID = hidValueCaps[index].reportID;
- printf("Report ID: %d\n", reportID);
- }
-
- if (hidValueCaps[index].isRange)
- printf("%X-%X:%d\t\t(%d<->%d)\t(%d<->%d)\t\t[%d * %d]\t\t••••\n",
- hidValueCaps[index].u.range.usageMin,
- hidValueCaps[index].u.range.usageMax,
- hidValueCaps[index].usagePage,
- hidValueCaps[index].logicalMin,
- hidValueCaps[index].logicalMax,
- hidValueCaps[index].physicalMin,
- hidValueCaps[index].physicalMax,
- hidValueCaps[index].bitSize,
- hidValueCaps[index].reportCount);
- else
- printf("%X:%d\t\t(%d<->%d)\t(%d<->%d)\t\t[%d * %d]\n",
- hidValueCaps[index].u.notRange.usage,
- hidValueCaps[index].usagePage,
- hidValueCaps[index].logicalMin,
- hidValueCaps[index].logicalMax,
- hidValueCaps[index].physicalMin,
- hidValueCaps[index].physicalMax,
- hidValueCaps[index].bitSize,
- hidValueCaps[index].reportCount);
-
- if (hidValueCaps[index].reportCount > 1)
- printf("••• Report Count > 1\n");
- }
-
- printf("\n\n");
- }
-
-
- void ClaimAndInstallHandler (void)
- {
- OSErr status = noErr;
- UHIDModuleConnectionID uHIDModuleConnectionID;
-
- if (gCurrentUHID_dispatchTable == nil)
- {
- printf("*** Error: have not specified a device\n");
- return;
- }
-
- if (gCurrentUHIDModuleConnectionID != 0)
- {
- printf("*** Error: Already have device active\n");
- return;
- }
-
- printf("Claiming the device\n");
-
- // claim the device
- status = (OSStatus) ((UHIDClaimDeviceProcPtr)(*(gCurrentUHID_dispatchTable->pUHIDClaimDevice))
- (&uHIDModuleConnectionID, 0));
- if (status)
- {
- printf("*** Error (%d) on Claim Device\n", status);
- return;
- }
-
- gCurrentUHIDModuleConnectionID = uHIDModuleConnectionID;
-
- // install the handler
-
- printf("Installing the handler\n");
-
- status = (OSStatus) ((UHIDInstallInterruptProcPtr)(*(gCurrentUHID_dispatchTable->pUHIDInstallInterrupt))
- (uHIDModuleConnectionID, myUniversalInterruptProc, 0));
- if (status)
- {
- printf("*** Error (%d) on Universal Interrupt Handler install\n", status);
- return;
- }
-
-
- }
-
- void RemoveHandlerAndRelease (void)
- {
- OSErr status = noErr;
-
- if (gCurrentUHID_dispatchTable == nil)
- {
- printf("*** Error have not specified a device\n");
- return;
- }
-
- if (gCurrentUHIDModuleConnectionID == 0)
- return;
-
- // remove the handler
-
- status = (OSStatus) (UHIDInstallInterruptProcPtr)(*(gCurrentUHID_dispatchTable->pUHIDInstallInterrupt))
- (gCurrentUHIDModuleConnectionID, nil, 0);
- if (status)
- printf("*** Error (%d) on Universal Interrupt Handler remove\n", status);
-
- // release the device
-
- status = (OSStatus) ((UHIDReleaseDeviceProcPtr)(*(gCurrentUHID_dispatchTable->pUHIDReleaseDevice))
- (gCurrentUHIDModuleConnectionID));
- if (status)
- printf("*** Error (%d) on release device\n", status);
-
- gCurrentUHIDModuleConnectionID = 0;
-
- }
-
- void myUniversalInterruptProc(void * theData, UInt32 /* refcon */)
- {
- //#pragma unused refcon
-
- UInt16 i;
- UInt8 *pRawData;
- OSErr status = noErr;
- UInt32 length;
- UInt32 index;
- SInt32 value;
-
- pRawData = (UInt8*)theData;
-
- switch (gPrint_AsType)
- {
- case kPrint_AsHex:
- case kPrint_AsBinary:
- for (i = 0; i < gMaxPacketSize; i++)
- {
- switch (gPrint_AsType)
- {
- case kPrint_AsHex:
- safeprintf("$%02X ", pRawData[i]);
- break;
-
- case kPrint_AsBinary:
- safeprintf("%d%d%d%d%d%d%d%d ", !!(pRawData[i]&0x80), !!(pRawData[i]&0x40),
- !!(pRawData[i]&0x20), !!(pRawData[i]&0x10),
- !!(pRawData[i]&0x08), !!(pRawData[i]&0x04),
- !!(pRawData[i]&0x02), !!(pRawData[i]&0x01));
- break;
- }
- }
- break;
-
- case kPrint_ParseButtons:
- length = gMaxUsageListLength;
-
- status = HIDGetButtons (kHIDInputReport, 0, gCurrentDownButtons, &length,
- gPreparsedDataRef, theData, gMaxPacketSize);
- if (status)
- safeprintf("HIDGetButtons error (%d)\n", status);
-
- safeprintf("%d buttons down: ", length);
-
- for (i = 0; i < length; i++)
- safeprintf("%d(%d) ", gCurrentDownButtons[i].usage, gCurrentDownButtons[i].usagePage);
- break;
-
- case kPrint_ParseBoth:
- status = HidP_PrintAllInputValues (0,(HIDPreparsedDataPtr) gPreparsedDataRef, theData, gMaxPacketSize);
-
- if (status)
- safeprintf("HidP_PrintAllInputValues error (%d)\n", status);
- break;
-
- case kPrint_SimulateISp:
- for (index = 0; index < gHIDElementCount; index++)
- {
- value = ParseElementValue (index, theData);
-
- safeprintf("%ld, ", value);
- }
- break;
- }
-
- safeprintf(" ");
-
- safeprintf("\n");
- }
-
- OSStatus HidP_PrintAllInputValues
- (UInt32 iCollection,
- HIDPreparsedDataPtr ptPreparsedData,
- char *psReport,
- int iReportLength)
- {
- HIDCollection *ptCollection;
- HIDReportItem *ptReportItem;
- UInt32 iR, iE, iU;
- SInt32 iValue;
- UInt32 iStart;
- UInt32 iReportItem;
- HIDUsageAndPage tUsageAndPage;
- /*
- * Disallow Null Pointers
- */
- if ((ptPreparsedData == NULL) || (psReport == NULL))
- return kHIDNullPointerErr;
- if (ptPreparsedData->hidTypeIfValid != kHIDOSType)
- return kHIDInvalidPreparsedDataErr;
- /*
- * Search only the scope of the Collection specified
- * Go through the ReportItems
- * Filter on ReportType
- */
- ptCollection = &ptPreparsedData->collections[iCollection];
-
- #if 0
- safeprintf ("Collection: count: %d\n", ptCollection->reportItemCount);
- #endif
-
- for (iR=0; iR<ptCollection->reportItemCount; iR++)
- {
- iReportItem = ptCollection->firstReportItem + iR;
- ptReportItem = &ptPreparsedData->reportItems[iReportItem];
-
- #if 0
- safeprintf ("Report Item: Type:%d, Size:%d, Start:%d, Count:%d, %s, %s\n",
- ptReportItem->reportType,
- ptReportItem->globals.reportSize,
- ptReportItem->startBit,
- ptReportItem->globals.reportCount,
- (ptReportItem->dataModes & kHIDDataArrayBit) == kHIDDataArray ? "isArray" : "notArray",
- (ptReportItem->dataModes & kHIDDataConstantBit) == kHIDDataConstant ? "isConstant" : "notConstant");
- #endif
-
-
- if ((ptReportItem->reportType == kHIDInputReport) &&
- (ptReportItem->dataModes & kHIDDataConstantBit) != kHIDDataConstant)
- {
- /*
- * Values
- */
- if (HIDIsVariable(ptReportItem))
- {
- int iUsageItem;
-
- iStart = ptReportItem->startBit;
- iUsageItem = ptReportItem->firstUsageItem;
-
- // loop for each usage item
- for (iU=0; iU<ptReportItem->usageItemCount; iU++)
- {
- OSStatus status = kHIDSuccess;
- HIDP_UsageItem *ptUsageItem;
-
- ptUsageItem = &ptPreparsedData->usageItems[iU];
-
- // if range, loop for each usage in range (is this right???)
- if (ptUsageItem->isRange && false) // •• diabled
- {
- int iUsageValue, min, max;
-
- min = ptUsageItem->usageMinimum;
- max = ptUsageItem->usageMaximum;
- if (max < min)
- {
- int temp;
- temp = min; min = max; max = temp;
- }
-
- for (iUsageValue = min; iUsageValue <= max; iUsageValue++)
- {
- status = HIDGetData(psReport, iReportLength, iStart,
- ptReportItem->globals.reportSize, &iValue,
- ((ptReportItem->globals.logicalMinimum < 0)
- ||(ptReportItem->globals.logicalMaximum < 0)));
- if (status)
- safeprintf ("\nHidP_GetData error = %d\n", status);
-
- iStart += ptReportItem->globals.reportSize;
-
- safeprintf("%d:\t%d (%x) ", iUsageValue, iValue, iValue);
-
- /*
- * Try to scale the data
- */
- #if 0
- status = HIDScaleUsageValueIn(ptReportItem,iValue,&iValue);
- if (status)
- safeprintf ("\nHidP_ScaleUsageValueIn error = %d\n", status);
- else
- safeprintf("[%d (%x)] ", iValue, iValue);
- #endif
- }
- }
- else // not range
- {
- status = HIDGetData(psReport, iReportLength, iStart,
- ptReportItem->globals.reportSize, &iValue,
- ((ptReportItem->globals.logicalMinimum < 0)
- ||(ptReportItem->globals.logicalMaximum < 0)));
- if (status)
- safeprintf ("\nHidP_GetData error = %d\n", status);
-
- iStart += ptReportItem->globals.reportSize;
-
- safeprintf("%d(%d-%d):\t%d (%x) ",
- ptUsageItem->usage, ptUsageItem->usageMinimum, ptUsageItem->usageMinimum,
- iValue, iValue);
-
- #if 0
- /*
- * Try to scale the data
- */
-
- status = HIDScaleUsageValueIn(ptReportItem,iValue,&iValue);
- if (status)
- safeprintf ("\nHidP_ScaleUsageValueIn error = %d\n", status);
- else
- safeprintf("[%d (%x)] ", iValue, iValue);
- #endif
- }
- }
- }
-
- /*
- * Buttons
- */
-
- else // is button
- {
- /*
- * Save Arrays and Bitmaps
- */
- iStart = ptReportItem->startBit;
- for (iE=0; iE<ptReportItem->globals.reportCount; iE++)
- {
- OSStatus status = kHIDSuccess;
-
- #if 0
- safeprintf ("startbits = %d (%x) of report item %d:%d\n", iStart, iStart, iR, iE);
- #endif
-
- if ((ptReportItem->dataModes & kHIDDataArrayBit) == kHIDDataArray)
- {
- status = HIDGetData(psReport, iReportLength, iStart, ptReportItem->globals.reportSize, &iValue, false);
- if (status)
- safeprintf ("\nHidP_GetData error = %d\n", status);
- #if 0
- else
- safeprintf ("Value = %d (%x) of array item %d:%d\n", iValue, iValue, iE, iR);
- #endif
- iStart += ptReportItem->globals.reportSize;
- HIDUsageAndPageFromIndex((HIDPreparsedDataRef)ptPreparsedData,ptReportItem,ptReportItem->globals.logicalMinimum+iE, &tUsageAndPage);
- safeprintf("%d:%d ", tUsageAndPage.usage, tUsageAndPage.usagePage);
-
- }
- else
- {
- iValue = 0;
- status = HIDGetData(psReport, iReportLength, iStart, 1, &iValue, false);
- if (status)
- safeprintf ("\nHidP_GetData error = %d\n", status);
- #if 0
- else
- safeprintf ("Value = %d (%x) of item %d:%d\n", iValue, iValue, iE, iR);
- #endif
-
- iStart++;
- if (iValue != 0)
- {
- HIDUsageAndPageFromIndex((HIDPreparsedDataRef)ptPreparsedData,ptReportItem,ptReportItem->globals.logicalMinimum+iE,&tUsageAndPage);
- safeprintf("%d:%d ", tUsageAndPage.usage, tUsageAndPage.usagePage);
- }
- }
- }
- }
- }
- }
- return kHIDSuccess;
- }
-
-
- int safeprintf(const char *format, ...)
- {
- va_list arglist;
- int return_value = 0;
- long len;
-
- va_start(arglist, format);
- return_value= vsprintf(&gInsertPrintfBuffer[gInsertIndex], format, arglist);
- va_end(arglist);
-
- len = strlen(&gInsertPrintfBuffer[gInsertIndex]);
-
- if (gInsertIndex + len < kPrintfBufferSize)
- gInsertIndex += len;
-
- return return_value;
- }
-
- void PrintPreparsedData (void)
- {
- HIDPreparsedDataPtr parsedData = (HIDPreparsedDataPtr) gPreparsedDataRef;
- char indent[] = " ";
-
- printf ("\n_Collections_\n");
- PrintCollectionItems(0, parsedData->collectionCount, indent);
-
- printf ("\n_ReportItems_\n");
- PrintReportItems(0, parsedData->reportItemCount, indent);
-
- printf ("\n_UsageItems_\n");
- PrintUsageItems(0, parsedData->usageItemCount, indent);
-
- printf ("\n_StringItems_: %d items\n", parsedData->stringItemCount);
-
- printf ("\n_DesigItems_: %d items\n", parsedData->desigItemCount);
-
- if (parsedData->stringItemCount > 0 || parsedData->desigItemCount > 0)
- printf ("••• Wow, it has strings or physical designators!\n");
-
- printf ("\n\n");
- }
-
- void PrintCollectionItems (UInt32 firstCollection, UInt32 collectionCount, char * indent)
- {
- HIDPreparsedDataPtr parsedData = (HIDPreparsedDataPtr) gPreparsedDataRef;
- unsigned index, start, end;
- char subIndent[32];
-
- sprintf (subIndent, "\t%s", indent);
-
- start = firstCollection;
- end = start + collectionCount;
-
- if (end > parsedData->collectionCount)
- {
- printf ("%s•••!!!collection integrity error! (%d, %d)\n", indent, end, parsedData->collectionCount);
- return;
- }
- else for (index = start; index < end; index++)
- {
- printf ("%sCollection (%X): %d (parent:%d, children:%d, firstChild:%d, nextSibling:%d)\n",
- indent,
- index,
- parsedData->collections[index].data,
- parsedData->collections[index].parent,
- parsedData->collections[index].children,
- parsedData->collections[index].firstChild,
- parsedData->collections[index].nextSibling);
-
- // print usage items in collection
- PrintUsageItems (parsedData->collections[index].firstUsageItem,
- parsedData->collections[index].usageItemCount,
- subIndent);
-
- // print report items in collection
- PrintReportItems (parsedData->collections[index].firstReportItem,
- parsedData->collections[index].reportItemCount,
- subIndent);
-
- }
- }
-
- void PrintReportItems (UInt32 firstReportItem, UInt32 reportItemCount, char * indent)
- {
- HIDPreparsedDataPtr parsedData = (HIDPreparsedDataPtr) gPreparsedDataRef;
- unsigned index, start, end;
- char subIndent[32];
-
- sprintf (subIndent, "\t%s", indent);
-
- start = firstReportItem;
- end = start + reportItemCount;
-
- if (end > parsedData->reportItemCount)
- {
- printf ("%s•••!!!report integrity error! (%d, %d)\n", indent, end, parsedData->reportItemCount);
- return;
- }
- else for (index = start; index < end; index++)
- {
- printf ("%sReportItem(%d): Page:%d\t(%d<->%d)\t(%d<->%d)\t[%d+(%d*%d)] %s %s\n",
- indent,
- index,
- parsedData->reportItems[index].globals.usagePage,
- parsedData->reportItems[index].globals.logicalMinimum,
- parsedData->reportItems[index].globals.logicalMaximum,
- parsedData->reportItems[index].globals.physicalMinimum,
- parsedData->reportItems[index].globals.physicalMaximum,
- parsedData->reportItems[index].startBit,
- parsedData->reportItems[index].globals.reportSize,
- parsedData->reportItems[index].globals.reportCount,
- (parsedData->reportItems[index].dataModes & kHIDDataConstantBit) ? "isConstant" : "",
- (parsedData->reportItems[index].dataModes & kHIDDataArrayBit) ? "isArray" : "");
-
- // print usage items in report item
- PrintUsageItems (parsedData->reportItems[index].firstUsageItem,
- parsedData->reportItems[index].usageItemCount,
- subIndent);
-
- if (parsedData->reportItems[index].stringItemCount > 0 || parsedData->reportItems[index].desigItemCount > 0)
- printf ("%sWow, it has strings or physical designators!\n", indent);
- }
- }
-
- void PrintUsageItems (UInt32 firstUsageItem, UInt32 usageItemCount, char * indent)
- {
- HIDPreparsedDataPtr parsedData = (HIDPreparsedDataPtr) gPreparsedDataRef;
- unsigned index, start, end;
-
- start = firstUsageItem;
- end = start + usageItemCount;
-
- if (end > parsedData->usageItemCount)
- {
- printf ("%s•••!!!usage integrity error! (%d, %d)\n", indent, end, parsedData->usageItemCount);
- return;
- }
- else for (index = start; index < end; index++)
- {
- if (parsedData->usageItems[index].isRange)
- printf ("%sUsage(%X): %d-%d\n", indent, index,
- parsedData->usageItems[index].usageMinimum,
- parsedData->usageItems[index].usageMaximum);
- else
- printf ("%sUsage(%d): %d\n", indent, index, parsedData->usageItems[index].usage);
- }
- }
-
- void SimulateISpEnumeration (void)
- {
- OSStatus err = noErr;
- UInt32 count;
-
-
- // get the overall capabilities of the device
- if (err == noErr)
- err = HIDGetCaps (gPreparsedDataRef, &gHIDCaps);
-
- // ••• for now, only work with devices that appear to be a joystick or gamepad
- if (err == noErr)
- {
- if (gHIDCaps.usagePage != kHIDPage_Generic ||
- (gHIDCaps.usage != kHIDUsage_Joystick && gHIDCaps.usage != kHIDUsage_Gamepad))
- {
- printf("•• matched to non-joystick, non-gamepad... bailing out\n");
- err = fnfErr;
- }
- }
-
- // allocate space for button caps
- if (err == noErr)
- {
- gHIDButtonCaps = (HIDButtonCaps *) NewPtrSysClear(sizeof(HIDButtonCaps) * gHIDCaps.numberInputButtonCaps);
- if (gHIDButtonCaps == nil) printf("•• could not allocate space for buttonCaps\n");
- if (gHIDButtonCaps == nil) err = memFullErr;
- }
-
- // get the button capabilities
- if (err == noErr)
- {
- count = gHIDCaps.numberInputButtonCaps;
- err = HIDGetButtonCaps (kHIDInputReport, gHIDButtonCaps, &gHIDCaps.numberInputButtonCaps, gPreparsedDataRef);
-
- if (count > gHIDCaps.numberInputButtonCaps)
- printf ("•• number of button caps increased! (%d->%d)\n", gHIDCaps.numberInputButtonCaps, count);
- else
- gHIDCaps.numberInputButtonCaps = count;
- }
-
- // allocate space for value caps
- if (err == noErr)
- {
- gHIDValueCaps = (HIDValueCaps *) NewPtrSysClear(sizeof(HIDValueCaps) * gHIDCaps.numberInputValueCaps);
- if (gHIDValueCaps == nil) printf("•• could not allocate space for valueCaps\n");
- if (gHIDValueCaps == nil) err = memFullErr;
- }
-
- // get the value capabilities
- if (err == noErr)
- err = HIDGetValueCaps (kHIDInputReport, gHIDValueCaps, &gHIDCaps.numberInputValueCaps, gPreparsedDataRef);
-
- // build HID elements
- if (err == noErr)
- err = BuildHIDElements ();
-
- // print HID elements
- if (err == noErr)
- err = PrintHIDElements ();
-
- // report error
- if (err)
- printf ("•• error = %d\n", err);
- }
-
- OSStatus PrintHIDElements (void)
- {
- UInt32 index;
-
- printf ("\nHIDElements (%d):\n", gHIDElementCount);
- for (index = 0; index < gHIDElementCount; index++)
- {
- switch (gHIDElements[index].type)
- {
- case kButtonElement:
- printf ("%2.2d:Button (%d): %X:%d, key:%d, (%d<->%d), str:%d\n",
- index,
- gHIDElements[index].capsIndex,
- gHIDElements[index].usage,
- gHIDElements[index].usagePage,
- gHIDElements[index].key,
- gHIDElements[index].min,
- gHIDElements[index].max,
- gHIDElements[index].stringIndex
- );
- break;
-
- case kValueElement:
- printf ("%2.2d:Value (%d): %X:%d, key:%d, (%d<->%d), str:%d\n",
- index,
- gHIDElements[index].capsIndex,
- gHIDElements[index].usage,
- gHIDElements[index].usagePage,
- gHIDElements[index].key,
- gHIDElements[index].min,
- gHIDElements[index].max,
- gHIDElements[index].stringIndex
- );
- break;
- }
- }
-
- printf ("\n");
-
- return noErr;
- }
-
- OSStatus BuildHIDElements (void)
- {
- OSStatus err = noErr;
- OSStatus initErr;
- UInt32 hidElementIndex = 0;
- UInt32 valueIndex;
- UInt32 buttonIndex;
- HIDUsage usage;
-
- // allocate space for HID elements
- if (err == noErr)
- {
- gHIDElementCount = CountHIDElements();
- gHIDElements = (HIDElement *) NewPtrSysClear(sizeof(HIDElement) * gHIDElementCount);
- if (gHIDElements == nil) printf("•• could not allocate space for HIDElements\n");
- if (gHIDElements == nil) err = memFullErr;
- }
-
- // add all values to the elements
- if (err == noErr)
- for (valueIndex = 0; valueIndex < gHIDCaps.numberInputValueCaps; valueIndex++)
- {
- HIDElement hidElement;
-
- if (gHIDValueCaps[valueIndex].reportCount != 1)
- printf("BuildHIDElements: value caps reportCount is not 1!\n");
-
- if (gHIDValueCaps[valueIndex].isRange)
- printf("BuildHIDElements: value caps is range!\n");
-
- hidElement.type = kValueElement;
- hidElement.capsIndex = valueIndex;
- hidElement.usagePage = gHIDValueCaps[valueIndex].usagePage;
- hidElement.min = gHIDValueCaps[valueIndex].logicalMin;
- hidElement.max = gHIDValueCaps[valueIndex].logicalMax;
-
- // NOTE: no devices I can find have values that are ranges, so this code may not be right!
- if (gHIDValueCaps[valueIndex].isRange)
- {
- for (usage = gHIDValueCaps[valueIndex].u.range.usageMin;
- usage <= gHIDValueCaps[valueIndex].u.range.usageMax;
- usage++)
- {
- hidElement.usage = usage;
- initErr = InitializeHIDElement(&hidElement);
-
- if (initErr == noErr)
- gHIDElements[hidElementIndex++] = hidElement;
- }
- }
- else // notRange
- {
- hidElement.usage = gHIDValueCaps[valueIndex].u.notRange.usage;
- initErr = InitializeHIDElement(&hidElement);
-
- if (initErr == noErr)
- gHIDElements[hidElementIndex++] = hidElement;
- }
- }
-
- // add all buttons to the elements
- if (err == noErr)
- for (buttonIndex = 0; buttonIndex < gHIDCaps.numberInputButtonCaps; buttonIndex++)
- {
- HIDElement hidElement;
- hidElement.type = kButtonElement;
- hidElement.capsIndex = buttonIndex;
- hidElement.usagePage = gHIDButtonCaps[buttonIndex].usagePage;
- hidElement.min = 0;
- hidElement.max = 1;
-
- printf("enumerating button (%d)\n", buttonIndex);
-
- // most buttons are reported as ranges of usage values
- if (gHIDButtonCaps[buttonIndex].isRange)
- {
- for (usage = gHIDButtonCaps[buttonIndex].u.range.usageMin;
- usage <= gHIDButtonCaps[buttonIndex].u.range.usageMax;
- usage++)
- {
- hidElement.usage = usage;
- initErr = InitializeHIDElement(&hidElement);
-
- if (initErr == noErr)
- gHIDElements[hidElementIndex++] = hidElement;
- }
- }
- else // notRange
- {
- hidElement.usage = gHIDButtonCaps[buttonIndex].u.notRange.usage;
- initErr = InitializeHIDElement(&hidElement);
-
- if (initErr == noErr)
- gHIDElements[hidElementIndex++] = hidElement;
- }
- }
-
- return err;
- }
-
- UInt32 CountHIDElements(void)
- {
- OSStatus err = noErr;
- UInt32 count = 0;
- UInt32 valueIndex;
- UInt32 buttonIndex;
-
- if (err == noErr)
- for (valueIndex = 0; valueIndex < gHIDCaps.numberInputValueCaps; valueIndex++)
- {
- if (gHIDValueCaps[valueIndex].isRange)
- count += (gHIDValueCaps[valueIndex].u.range.usageMax - gHIDValueCaps[valueIndex].u.range.usageMin) + 1;
- else // notRange
- count++;
- }
-
- // count all buttons
- if (err == noErr)
- for (buttonIndex = 0; buttonIndex < gHIDCaps.numberInputButtonCaps; buttonIndex++)
- {
- if (gHIDButtonCaps[buttonIndex].isRange)
- count += (gHIDButtonCaps[buttonIndex].u.range.usageMax - gHIDButtonCaps[buttonIndex].u.range.usageMin) + 1;
- else // notRange
- count++;
- }
-
- return count;
- }
-
- OSStatus InitializeHIDElement(HIDElement * hidElement)
- {
- OSStatus err = noErr;
- SInt32 stringIndex = -1;
-
- switch (hidElement->type)
- {
- case kButtonElement:
- if (hidElement->usagePage != kHIDPage_Button)
- printf("InitializeHIDElement: button found not on button page (%d)\n", hidElement->usagePage);
-
- if (hidElement->usagePage != kHIDPage_Button)
- return kHIDBadParameterErr;
-
- switch (hidElement->usage)
- {
- case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
- case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16:
- hidElement->key = kUSB_button1_element + (hidElement->usage - 1);
- stringIndex = kStrList_DefaultNames_Button1 + (hidElement->usage - 1);
- break;
- default:
- return kHIDBadParameterErr;
- }
- break;
-
- case kValueElement:
- if (hidElement->usagePage == kHIDPage_Generic)
- switch (hidElement->usage)
- {
- case kHIDUsage_X:
- hidElement->key = kUSB_xaxis_element;
- stringIndex = kStrList_DefaultNames_XAxis;
- break;
-
- case kHIDUsage_Y:
- hidElement->key = kUSB_yaxis_element;
- stringIndex = kStrList_DefaultNames_YAxis;
- break;
-
- case kHIDUsage_Z:
- hidElement->key = kUSB_axis_element;
- stringIndex = kStrList_DefaultNames_Axis;
- break;
-
- case kHIDUsage_Rx:
- hidElement->key = kUSB_axis_element;
- stringIndex = kStrList_DefaultNames_Axis;
- break;
-
- case kHIDUsage_Ry:
- hidElement->key = kUSB_axis_element;
- stringIndex = kStrList_DefaultNames_Axis;
- break;
-
- case kHIDUsage_Rz:
- hidElement->key = kUSB_rudder_element;
- stringIndex = kStrList_DefaultNames_Twist;
- break;
-
- case kHIDUsage_Slider:
- hidElement->key = kUSB_throttle_element;
- stringIndex = kStrList_DefaultNames_Throttle;
- break;
-
- case kHIDUsage_Dial:
- case kHIDUsage_Wheel:
- hidElement->key = kUSB_trim_element;
- stringIndex = kStrList_DefaultNames_Trim;
- break;
-
- case kHIDUsage_HatSwitch:
- hidElement->key = kUSB_povhat_element;
- stringIndex = kStrList_DefaultNames_POVHat;
- break;
- }
- else if (hidElement->usagePage == kHIDPage_Simulation)
- switch (hidElement->usage)
- {
- case kHIDUsage_Rudder:
- hidElement->key = kUSB_rudder_element;
- stringIndex = kStrList_DefaultNames_Rudder;
- break;
-
- case kHIDUsage_Throttle:
- hidElement->key = kUSB_throttle_element;
- stringIndex = kStrList_DefaultNames_Throttle;
- break;
- }
- break;
-
- default:
- printf("InitializeHIDElement: unknown type (%d)\n", hidElement->type);
- err = kHIDBadParameterErr;
- break;
- }
-
- hidElement->stringIndex = stringIndex;
-
- return err;
- }
-
- SInt32 ParseElementValue (UInt32 inElementIndex, Ptr inBuffer)
- {
- OSStatus err = noErr;
- HIDUsage usageList[kUSB_button16_element];
- UInt32 usageListSize = kUSB_button16_element;
- UInt32 index;
- HIDElement * hidElement = &gHIDElements[inElementIndex];
- SInt32 usageValue;
-
- switch (hidElement->type)
- {
- case kButtonElement:
- // for now, we'll only look at buttons on the button page
- err = HIDGetButtonsOnPage (kHIDInputReport,
- kHIDPage_Button,
- 0,
- usageList,
- &usageListSize,
- gPreparsedDataRef,
- inBuffer,
- gMaxPacketSize);
-
- // confirm we succeeded
- if (err != noErr && err != kHIDUsageNotFoundErr)
- safeprintf ("••ParseElementValue: HIDGetButtonsOnPage failed (%d)", err);
- if (err != noErr)
- break;
-
- // walk the returned usage list
- for (index = 0; index < usageListSize; index++)
- {
- // if our usage is in the usage list, then we are down
- if (usageList[index] == hidElement->usage)
- return 1;
- }
-
- // we were not in the list, so we are up
- return 0;
-
- case kValueElement:
- // get the usage value
- err = HIDGetUsageValue (kHIDInputReport,
- hidElement->usagePage,
- 0, // •• this might be faster if we store collection and pass here
- hidElement->usage,
- &usageValue,
- gPreparsedDataRef,
- inBuffer,
- gMaxPacketSize);
-
- // confirm we succeeded
- if (err != noErr && err != kHIDUsageNotFoundErr)
- safeprintf ("••ParseElementValue: HIDGetUsageValue failed (%d)", err);
- if (err != noErr)
- break;
-
- // handle dpads
- if (false && hidElement->key == kUSB_povhat_element)
- {
- if (usageValue < hidElement->min || usageValue > hidElement->max)
- usageValue = kISpPadIdle;
- else
- {
- SInt32 normalized = usageValue - hidElement->min;
- SInt32 normalizedMax = hidElement->max - hidElement->min;
-
- // avoid devide by zero
- if (normalizedMax == 0) return kISpPadIdle;
-
- // rescale value
- normalized = ((normalized * 7)) / normalizedMax;
- switch (normalized)
- {
- case 0: usageValue = kISpPadUp; break;
- case 1: usageValue = kISpPadUpRight; break;
- case 2: usageValue = kISpPadRight; break;
- case 3: usageValue = kISpPadDownRight; break;
- case 4: usageValue = kISpPadDown; break;
- case 5: usageValue = kISpPadDownLeft; break;
- case 6: usageValue = kISpPadLeft; break;
- case 7: usageValue = kISpPadUpLeft; break;
-
- default:usageValue = kISpPadIdle; break; // should not get here
- }
- }
- }
-
- return usageValue;
- }
-
- return 0;
- }
-